:D 이제 여러분들은 책을 정리할때가 다가왔습니다. 마지막 까지 잘 해봅시다.
책의 전체 내용을 뭉뚱그려서 여지껏 배워온 흐름대로 개발을 진행 합니다.
개발 흐름은 다음과 같습니다.
OOAD 스타일 개발 순서
1. 특징리스트 : 상위 수준에서의 애플리케이션 동작에 대한 이해
2. 유스케이스다이어그램 : 수행될 프로세스와 외부영향에 대한 결정
3. 문제점 분해하기 : 기능단위인 모듈로 분해하여 어떤걸 먼저 할지 순서 결정
4. 요구사항 : 각 모듈에 대한 개별적 요구 사항을 이해하고 큰 그림 만들기
5. 도메인 분석 : 어떻게 유스케이스 들이 애플리케이션의 객체들로 사상되는지 이해하고 공감대 형성
6. 사전설계 : 객체들에 대한 세부 내용을 채워 넣고 객체간에 패턴을 적용
7. 구현 : 코드를 작성 하고 테스트 하여 동작하는걸 확인하고 완성한다.(지속적 테스팅 TDD 구현)
8. 출하 : 잔금수거 하기 :D
ps.
사전설계와 구현 부분에서는 OOP언어의 특성을 최대한 발휘 해서 정형화된 패턴을 찾아 최대한 유연하게 개발 합시다.
그래여 유지보수가 쉬워지고 재사용 하기 편해지니까요. 이건 정말 중요해요. 제대로 안될경우에는 잔금 수거가 힘들어지니까요.
회사가 망할수도 있어요. 갑이 계속 트집을 잡거든요.
책 524 페이지를 보시면 우리가 만들어야할 프로젝트의 요구사항 명세서를 간단한 작업기술서 형태로 제공 하고 있네요
한번 살펴 보고 갑시다.
START! 객체마을 지하철 노선도
특징
보통 하나의 특징을 만족시키기 위해서는 서너개의 요구 사항이 필요할수 있습니다.
유즈케이스 다이어그램을 통해서 하나의 특징 리스트를 어떻게 세부 항목과 구분하는 확인해 봅시다
객체마을 지하철 노선도 의 특징리스트는 다음과 같습니다.
1. 지하철 노선의 역들을 표시하기
2. 겹쳐진 노선을 포함하여 다수의 지하철 노선을 적재하기
3. 두 역 사이의 유효한 경로를 찾기
4. 두 역 사이에 있는 특정 경로의 방향 표시 출력하기
그림들어갈 위치
1.Subway
1.1 Subway 표시하기에 대한 정의
1.2 요구사항
1.3 유스케이스 동작여부 검증
1.4 분석과 설계
지하철 노선 적재하기 유스케이스
1.관리자가 역과 노선이 담긴 파일을 공급한다.
2.시스템은 역의 이름을 읽어 온다.
3.시스템은 역이 이미 존재하지 않는지 검증한다.
4.시스템은 지하철에 새로운 역을 추가한다.
5.시스템은 모든 역이 추가될 때까지 단계 2~4를 반복한다.
6.시스템은 추가할 노선의 이름을 읽어 들인다.
7.시스템은 연결되어 있는 두 역을 읽어 들인다.
8.시스템은 역들이 존재하는지 검증한다.
9.시스템은 현재 노선의 두 역 사이에 양방향으로 진행 가능한 새로운 연결을 생성한다.
10.시스템은 노선이 완선될 때까지 단계 7~9를 반복한다.
11.시스템은 모든 노선이 입력될 ?까지 단계 6~10을 반복한다.
| Station.java | Connection.java | Subway.java |
|---|---|---|
| {code} package com.oracleclub.study.ooad.ten; public class Station { private String name; |
public Station(String name) {
this.name =name;
}
public String getName() {
return name;
}
public boolean equals(Object obj) {
if (obj instanceof Station) {
Station otherStation = (Station) obj;
if (otherStation.getName().equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
public int hashCode() {
return name.toLowerCase().hashCode();
}
}
|
package com.oracleclub.study.ooad.ten;
public class Connection {
private Station station1, station2;
private String lineName;
public Connection (Station station1, Station station2, String lineName) {
this.station1 = station1;
this.station2 = station2;
this.lineName = lineName;
}
public Station getStation1() {
return station1;
}
public Station getStation2() {
return station2;
}
public String getLineName() {
return lineName;
}
}
|
package com.oracleclub.study.ooad.ten;
import java.util.LinkedList;
import java.util.List;
public class Subway {
private List stations;
private List connections;
public Subway () {
this.stations = new LinkedList();
this.connections = new LinkedList();
}
public void addStation(String stationName) {
if (!this.hasStation(stationName)) {
Station station = new Station(stationName);
stations.add(station);
}
}
private boolean hasStation(String station2) {
// TODO Auto-generated method stub
return stations.contains(new Station(station2));
}
public void addConnection(String stationName1,
String stationName2,
String lineName) {
if ((this.hasStation(stationName1)) &&
(this.hasStation(stationName2))) {
Station station1 = new Station(stationName1);
Station station2 = new Station(stationName2);
Connection connection = new Connection(station1, station2, lineName);
connections.add(connection);
connections.add(new Connection(station2, station1, connection.getLineName()));
}else {
throw new RuntimeException("Invalid connection");
}
}
}
|
|| SubwayLoader.java ||Subway.java||
|
package com.oracleclub.study.ooad.ten;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class SubwayLoader {
private Subway subway;
public SubwayLoader(){
this.subway = new Subway();
}
public Subway loadFromFile(File subwayFile) throws IOException {
BufferedReader reader = new BufferedReader(
new FileReader(subwayFile)
);
loadStations(subway, reader);
String lineName = reader.readLine();
while ((lineName != null) && (lineName.length() > 0)) {
loadLine(subway, reader, lineName);
}
return subway;
}
private void loadStations(Subway subway2, BufferedReader reader) throws IOException{
// TODO Auto-generated method stub
String currentline;
currentline = reader.readLine();
while (currentline.length() > 0) {
subway2.addStation(currentline);
currentline = reader.readLine();
}
}
private void loadLine(Subway subway, BufferedReader reader, String lineName) throws IOException{
String stationName1, stationName2;
stationName1 = reader.readLine();
stationName2 = reader.readLine();
while ((stationName2!= null) && (stationName2.length() > 0)) {
subway.addConnection(stationName1, stationName2, lineName);
stationName1 = stationName2;
stationName2 = reader.readLine();
}
}}
|
|
import java.util.*;
public class Subway
{
private List stations;
private List connections;
private Map network;
public Subway() {
this.stations = new LinkedList();
this.connections = new LinkedList();
this.network = new HashMap();
}
public void addStation(String stationName) {
if (!this.hasStation(stationName)) {
Station station = new Station(stationName);
stations.add(station);
}
}
public boolean hasStation(String stationName) {
return stations.contains(new Station(stationName));
}
public void addConnection(String station1Name, String station2Name, String lineName) {
if ((this.hasStation(station1Name)) && (this.hasStation(station2Name))) {
Station station1 = new Station(station1Name);
Station station2 = new Station(station2Name);
Connection connection = new Connection(station1, station2, lineName);
connections.add(connection);
connections.add(new Connection(station2, station1, connection.getLineName()));
addToNetwork(station1, station2);
addToNetwork(station2, station1);
}
else
{
throw new RuntimeException("Invalid connection: " + station1Name + ", " + station2Name + ", " + lineName + "");
}
}
private void addToNetwork(Station station1, Station station2) {
if (network.keySet().contains(station1)) {
List connectingStations = (List) network.get(station1);
if (!connectingStations.contains(station2)) {
connectingStations.add(station2);
}
} else {
List connectingStations = new LinkedList();
connectingStations.add(station2);
network.put(station1, connectingStations);
}
}
public List getDirections(String startStationName, String endStationName) {
if (!this.hasStation(startStationName) || !this.hasStation(endStationName))
{
throw new RuntimeException("Stations entered do not exist on this subway");
}
Station start = new Station(startStationName);
Station end = new Station(endStationName);
List route = new LinkedList();
List reachableStations = new LinkedList();
Map previousStations = new HashMap();
List neighbors = (List)network.get(start);
for (Iterator i = neighbors.iterator(); i.hasNext(); ) {
Station station = (Station) i.next();
if (station.equals(end)) {
route.add(getConnection(start, end));
return route;
} else {
reachableStations.add(station);
previousStations.put(station, start);
}
}
List nextStations = new LinkedList();
nextStations.addAll(neighbors);
Station currentStation = start;
searchLoop:
for (int i = 1; i < stations.size(); i++) {
List tmpNextStations = new LinkedList();
for (Iterator j = nextStations.iterator(); j.hasNext(); ) {
Station station = (Station) j.next();
reachableStations.add(station);
currentStation = station;
List currentNeighbors = (List) network.get(currentStation);
for (Iterator k = currentNeighbors.iterator(); k.hasNext(); ) {
Station neighbor = (Station) k.next();
if (neighbor.equals(end)) {
reachableStations.add(neighbor);
previousStations.put(neighbor, currentStation);
break searchLoop;
} else if (!reachableStations.contains(neighbor)) {
reachableStations.add(neighbor);
tmpNextStations.add(neighbor);
previousStations.put(neighbor, currentStation);
}
}
}
nextStations = tmpNextStations;
}
//We've found the path now!
boolean keepLooping = true;
Station keyStation = end;
Station station;
while (keepLooping) {
station = (Station) previousStations.get(keyStation);
route.add(0, getConnection(station, keyStation));
if (start.equals(station)) {
keepLooping = false;
}
keyStation = station;
}
return route;
}
private Connection getConnection(Station station1, Station station2) {
for (Iterator i = connections.iterator(); i.hasNext(); ) {
Connection connection = (Connection) i.next();
Station one = connection.getStation1();
Station two = connection.getStation2();
if ((station1.equals(one)) && station2.equals(two)) {
return connection;
}
}
return null;
}
public boolean hasConnection(String station1Name, String station2Name, String lineName) {
Station station1 = new Station(station1Name);
Station station2 = new Station(station2Name);
for (Iterator i = connections.iterator(); i.hasNext(); ) {
Connection connection = (Connection) i.next();
if (connection.getLineName().equalsIgnoreCase(lineName)) {
if ((connection.getStation1().equals(station1)) &&
(connection.getStation2().equals(station2)))
{
return true;
}
}
}
return false;
}
}
|
위코드를 subversion을 통해서 동기화 한다음에 테스트 해보시고 결과를 확인해 보시기 바랍니다. ( package com.oracleclub.study.ooad.ten )
위 작업을 통해서 *지하철 노선 적재하기* 라는 유스케이스를 완성 하였습니다. 다음은
*길찾기* 유스케이스를 작성하기 위해 요구사항 단계로 돌아가서 지금까지 한 내용을 반복 합니다.
같은 단계를 거치므로 생략 하고 각 단계에서 발생될수 있는 의문사항에 대해 살펴보고 마무리 하도록 하겠습니다.
다익스트라알고리즘
!1.GIF!
* 1. 맨처음 S에서 갈 수 있는 곳들을 처음 S에서 갈수있는 최단거리로 놓는다.
* 2. S에서 모든 정점중 가장 거리가 짧은 정점을 구한다.(여짓것 구한 것들을 토대로)
만약 그 정점을 X라고 하면, 현제 구한 S~>X는 S에서 X까지 가는 최단거리이다.
* 3. X를 경유하여 (S~>X + X->Y) < (S~>Y)라고 한다면, S~>Y를 X를 경유한 S~X + X->Y로 대체한다.
* 4. 2번부터 다시 반복한다.( n-1번 )
!1214581885720.gif!
h3. 10.2.4 출하
돈받아야지요.
h2. 10.3 정리하기
h2. 문서에 대하여
* 이 문서는 [Head First Object-Oriented Analysis & Design|http://book.naver.com/bookdb/book_detail.php?bid=2920750]을 정리한 내용 입니다.
* 이 문서는 [오라클클럽|http://www.gurubee.net] [자바 웹개발자 스터디|제3차 자바 웹개발자 스터디] 모임에서 작성하였습니다.
* 이 문서를 다른 블로그나 홈페이지에 게재할 경우에는 출처를 꼭 밝혀 주시면 고맙겠습니다.~^\^